//业务层
#ifndef CHATSERVICE_H
#define CHATSERVICE_H
#include"usermodel.hpp"
#include"offlinemessagemodel.hpp"
#include"friendmodel.hpp"
#include"groupmodel.hpp"
#include"redis.hpp"
#include "json.hpp"
#include <muduo/net/TcpConnection.h>
#include<mutex>
#include <unordered_map>
#include <functional>
using namespace std;
using namespace muduo;
using namespace muduo::net;
using json = nlohmann::json;
// 处理不同消息类型的回调函数
using MsgHandler = std::function<void(const TcpConnectionPtr &conn, json &js, Timestamp)>;
// 聊天服务器业务类
//  单例:只能同时有一个ChatService对象
class ChatService
{
public:
    // 获取单例对象
    static ChatService *instance();

    // 获取消息对应的Handler
    MsgHandler getHandler(int msgid);
    //处理客户端异常退出
    void clientCloseException(const TcpConnectionPtr& conn);
    //一对一聊天消息回调
    void oneChat(const TcpConnectionPtr &conn, json &js, Timestamp time);
    //服务器异常后，重置业务
    void reset();
    //创建群组消息回调
    void createGroup(const TcpConnectionPtr &conn, json &js, Timestamp time);
    //加入群组消息回调
    void addGroup(const TcpConnectionPtr &conn, json &js, Timestamp time);
    //群聊天消息的消息回调
    void groupChat(const TcpConnectionPtr &conn, json &js, Timestamp time);
    //处理redis的订阅消息
    void handleRedisSubscribeMessage(int ,string);

private:
    // 登入回调
    void login(const TcpConnectionPtr &conn, json &js, Timestamp time);
    // 注册回调
    void reg(const TcpConnectionPtr &conn, json &js, Timestamp time);
    //处理注销
    void loginout(const TcpConnectionPtr &conn, json &js, Timestamp time);
    //添加好友业务
    void addFriend(const TcpConnectionPtr &conn, json &js, Timestamp time);
    ChatService();
    // 存放消息的id和其对应的业务处理函数
    unordered_map<int, MsgHandler> _msgHandlerMap;
    //存储在线用户的连接.需要保证线程安全
    unordered_map<int,TcpConnectionPtr> _userConnMap;
    //互斥锁，保证_userConnMap的线程安装
    mutex _connMutex;
    //数据操作类对象
    UserModel _userModel;
    //离线消息操作对象
    OfflineMsgModel _offlineMsgModel;
    //好友信息操作对象
    FriendModel _friendModel;
    //群组功能操作对象
    GroupModel _groupmodel;
    //redis操作对象
    Redis _redis;
};

#endif